package com.haojiang.mh.remote.ui.frag

import android.content.res.Resources
import android.graphics.Paint
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.view.View
import android.widget.EditText
import android.widget.NumberPicker
import android.widget.TextView
import android.widget.TimePicker
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import cn.com.heaton.blelibrary.ble.utils.ByteUtils
import com.haojiang.mh.AppContext
import com.haojiang.mh.R
import com.haojiang.mh.remote.adapter.AlarmMemFragAdapter
import com.haojiang.mh.remote.adapter.AlarmMsgFragAdapter
import com.haojiang.mh.remote.base.BaseFrag
import com.haojiang.mh.remote.bean.TaskData
import com.haojiang.mh.remote.enums.EArea
import com.haojiang.mh.remote.event.FunChangeEvent
import com.haojiang.mh.remote.event.ReceiverEvent
import com.haojiang.mh.remote.utils.BleUtil
import com.haojiang.mh.remote.utils.BleUtil.Companion.getFinalBytes
import com.haojiang.mh.remote.utils.BleUtil.Companion.isDevConncted
import com.haojiang.mh.remote.utils.BleUtil.Companion.lastConnect
import com.haojiang.mh.remote.utils.BleUtil.Companion.taskRun
import com.haojiang.mh.remote.utils.CmdKey
import com.haojiang.mh.remote.utils.Constant
import com.haojiang.mh.remote.utils.Constant.RX_ALARM_CANCEL_SUCCESS
import com.haojiang.mh.remote.utils.Constant.RX_ALARM_SET_SUCCESS
import com.haojiang.mh.remote.utils.Util.Companion.playSound
import kotlinx.android.synthetic.main.frag_alarm.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.reflect.Field
import java.util.*


class AlarmFrag : BaseFrag() {

    private val alarmMemFragAdapter by lazy { AlarmMemFragAdapter() }
    private val alarmMsgFragAdapter by lazy { AlarmMsgFragAdapter() }
    private var goldenColor: Int = 0
    private var whiteColor: Int = 0

    private val TOTAL_MINUTE: Int = 1440
    private var mHour: Int = -1
    private var mMinute: Int = -1
    private var cmdCode: String? = null

    private val onClickListener = object : View.OnClickListener {
        override fun onClick(v: View?) {
            playSound()
            if (!isDevConncted()) {
                showToast("请先连接设备再执行此操作")
                return
            }
            when (v!!.id) {
                R.id.tvSetting -> {
                    val memList = alarmMemFragAdapter.getMemList()
                    val msgList = alarmMsgFragAdapter.getMsgList()
                    if (memList.size <= 0 && msgList.size <= 0) {
                        showToast("选择不能为空")
                        return
                    }

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        setAlarmData(memList, msgList)
                    }
                }

                R.id.tvCancel -> {
                    val taskList: ArrayList<TaskData> = arrayListOf(
                        TaskData(Runnable {
                            lastConnect.bleDeviceList.forEach {
                                BleUtil.deviceDataSend(it, Constant.TX_ALARM_CANCLE1)
                            }
                        }, 300),
                        TaskData(Runnable {
                            lastConnect.bleDeviceList.forEach {
                                BleUtil.deviceDataSend(it, Constant.TX_ALARM_CANCLE2)
                            }
                        }, 300),
                    )
                    BleUtil.taskRun(taskList)
                }
                else -> {
                }
            }
        }
    }

    //        for (i in 0 until minuteBytes.size) {
//            LogUtil.e(minuteBytes.get(i).toString() + "时间")
//        }

    @RequiresApi(Build.VERSION_CODES.M)
    private fun setAlarmData(memList: ArrayList<String>, msgList: ArrayList<String>) {
        var totalMinute = TOTAL_MINUTE
        var minuteBytes = ByteUtils.intToBytes(totalMinute)   //把1440分成两个byte
        val hour = Calendar.getInstance()[Calendar.HOUR_OF_DAY]
        val minute = Calendar.getInstance()[Calendar.MINUTE]

        var memByte: ByteArray? = null
        var msgByte: ByteArray? = null
        if (memList.size > 0) {
            memByte = ByteUtils.hexStr2Bytes(memList.get(0))
        }
        if (msgList.size > 0) {
            if (msgList.size == 2) {
                msgByte = ByteUtils.hexStr2Bytes(CmdKey.MSG_HEAD_FOOT_BOTH_ON)  //如果两个按摩器同时选中
            } else {
                msgByte = ByteUtils.hexStr2Bytes(msgList.get(0))
            }
        }

        if (mMinute - minute == 0 && mHour - hour == 0) {   //设置时间和当前时间一样
            combineCmd(minuteBytes, memByte, msgByte)   //发送一天的分钟数1440
        } else {
            if (mMinute - minute >= 0) {
                if (mHour - hour >= 0) {
                    totalMinute = (mHour - hour) * 60 + (mMinute - minute)
                } else {
                    totalMinute = (mHour + 24 - hour) * 60 + (mMinute - minute)
                }
            } else {
                if (mHour - hour > 0) {
                    totalMinute = (mHour - 1 - hour) * 60 + (mMinute + 60 - minute)
                } else {
                    totalMinute = (mHour + 24 - 1 - hour) * 60 + (mMinute + 60 - minute)
                }
            }
            minuteBytes = ByteUtils.intToBytes(totalMinute)
            combineCmd(minuteBytes, memByte, msgByte)
        }
    }

    private fun combineCmd(minuteBytes: ByteArray?, memByte: ByteArray?, msgByte: ByteArray?) {
//        LogUtil.e("=记忆位置=" + memByte + "=按摩器=" + msgByte)
        if (memByte == null) {   //如果记忆位置为空
            sendAlarmData(minuteBytes!!, msgByte) //只发送按摩器
        } else if (msgByte == null) {        //如果按摩器为空
            sendAlarmData(minuteBytes!!, memByte) //只发送记忆位置
        } else {

            when (ByteUtils.bytes2HexStr(memByte).toUpperCase(Locale.ROOT)) {
                CmdKey.TV_BACK_POS -> {
                    when (ByteUtils.bytes2HexStr(msgByte).toUpperCase(Locale.ROOT)) {
                        CmdKey.MSG_HEAD_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.tv_head_on))
                            )
                        }
                        CmdKey.MSG_FOOT_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.tv_foot_on))
                            )
                        }
                        CmdKey.MSG_HEAD_FOOT_BOTH_ON -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.tv_all_on))
                            )
                        }
                    }
                }

                CmdKey.ZG_BACK_POS -> {
                    when (ByteUtils.bytes2HexStr(msgByte).toUpperCase(Locale.ROOT)) {
                        CmdKey.MSG_HEAD_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.zg_head_on))
                            )
                        }
                        CmdKey.MSG_FOOT_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.zg_foot_on))
                            )
                        }
                        CmdKey.MSG_HEAD_FOOT_BOTH_ON -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.zg_all_on))
                            )
                        }
                    }
                }

                CmdKey.SNORE_BACK_POS -> {
                    when (ByteUtils.bytes2HexStr(msgByte).toUpperCase(Locale.ROOT)) {
                        CmdKey.MSG_HEAD_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.snore_head_on))
                            )
                        }
                        CmdKey.MSG_FOOT_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.snore_foot_on))
                            )
                        }
                        CmdKey.MSG_HEAD_FOOT_BOTH_ON -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.snore_all_on))
                            )
                        }
                    }
                }

                CmdKey.LOUNGE_BACK_POS -> {
                    when (ByteUtils.bytes2HexStr(msgByte).toUpperCase(Locale.ROOT)) {
                        CmdKey.MSG_HEAD_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.lounge_head_on))
                            )
                        }
                        CmdKey.MSG_FOOT_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.lounge_foot_on))
                            )
                        }
                        CmdKey.MSG_HEAD_FOOT_BOTH_ON -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.lounge_all_on))
                            )
                        }
                    }
                }

                CmdKey.M1_BACK_POS -> {
                    when (ByteUtils.bytes2HexStr(msgByte).toUpperCase(Locale.ROOT)) {
                        CmdKey.MSG_HEAD_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.m1_head_on))
                            )
                        }
                        CmdKey.MSG_FOOT_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.m1_foot_on))
                            )
                        }
                        CmdKey.MSG_HEAD_FOOT_BOTH_ON -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.m1_all_on))
                            )
                        }
                    }
                }

                CmdKey.M2_BACK_POS -> {
                    when (ByteUtils.bytes2HexStr(msgByte).toUpperCase(Locale.ROOT)) {
                        CmdKey.MSG_HEAD_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.m2_head_on))
                            )
                        }
                        CmdKey.MSG_FOOT_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.m2_foot_on))
                            )
                        }
                        CmdKey.MSG_HEAD_FOOT_BOTH_ON -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.m2_all_on))
                            )
                        }
                    }
                }

                CmdKey.M3_BACK_POS -> {
                    when (ByteUtils.bytes2HexStr(msgByte).toUpperCase(Locale.ROOT)) {
                        CmdKey.MSG_HEAD_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.m3_head_on))
                            )
                        }
                        CmdKey.MSG_FOOT_INTENSITY_INC -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.m3_foot_on))
                            )
                        }
                        CmdKey.MSG_HEAD_FOOT_BOTH_ON -> {
                            sendAlarmData(
                                minuteBytes!!,
                                ByteUtils.hexStr2Bytes(context.getString(R.string.m3_all_on))
                            )
                        }
                    }
                }
            }
        }
    }

    private fun sendAlarmData(minuteBytes: ByteArray, cmdByte: ByteArray?) {
//        val low8Bytes = getFinalBytes(byteArrayOf(0x6E, 0x05, minuteBytes[0], 0x00, 0x00))
//        val high8Bytes = getFinalBytes(byteArrayOf(0x6E, 0x06, minuteBytes[1], cmdByte!!.get(0), 0x00))
        val taskList: ArrayList<TaskData> = arrayListOf(
            TaskData(Runnable {
                lastConnect.bleDeviceList.forEach {
//                    LogUtil.e("0x6E 0x05 " + ByteUtils.bytes2HexStr(minuteBytes) + " 0x00")
                    BleUtil.deviceDataSend(
                        it,
                        getFinalBytes(byteArrayOf(0x6E, 0x05, minuteBytes[3], 0x00, 0x00))
                    )
                }
            }, 300),
            TaskData(Runnable {
                lastConnect.bleDeviceList.forEach {
                    BleUtil.deviceDataSend(
                        it,
                        getFinalBytes(
                            byteArrayOf(
                                0x6E,
                                0x06,
                                minuteBytes[2],
                                cmdByte!!.get(0),
                                0x00
                            )
                        )
                    )
                }
            }, 300),
        )
        taskRun(taskList)
        cmdCode = ByteUtils.bytes2HexStr(cmdByte!!)
//        LogUtil.e("cmdCode=" + cmdCode)
//        low8Bytes.forEach {
//            LogUtil.e(it.toString() + "低位")
//        }
//        high8Bytes.forEach {
//            LogUtil.e(it.toString()+ "高位")
//        }
//        LogUtil.e(low8Bytes.toString() + "==")
//        LogUtil.e(high8Bytes.toString() + "==")
//        utils.sendBytesData(arrayOf(0x6E, 0x05, bytes[3], 0x00)) //低八位
//        utils.threadSleep(300)
//        utils.sendBytesData(arrayOf(0x6E, 0x06, bytes[2], utils.hexStringToBytes(command).get(0))) //高八位
//        utils.threadSleep(300)
    }

    override fun onLayoutId(): Int {
        return R.layout.frag_alarm
    }


    override fun initView() {
//        LogUtil.e("闹钟视图被加载")
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
//        return View.inflate(context, R.layout.frag_alarm, null)
    }


    override fun initListener() {
        rvMemory.layoutManager = LinearLayoutManager(context)
        rvMemory.adapter = alarmMemFragAdapter
        rvMassage.layoutManager = LinearLayoutManager(context)
        rvMassage.adapter = alarmMsgFragAdapter

        timePicker.setIs24HourView(false)
        setTimePicker()

        tvSetting.setOnClickListener(onClickListener)
        tvCancel.setOnClickListener(onClickListener)

        timePicker.setOnTimeChangedListener(object : TimePicker.OnTimeChangedListener {
            override fun onTimeChanged(view: TimePicker?, hourOfDay: Int, minute: Int) {
                mHour = hourOfDay
                mMinute = minute
            }
        })
        mHour = -1
        mMinute = 1
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onReceiverEvent(event: ReceiverEvent) {
        when (event.rxData) {
            RX_ALARM_SET_SUCCESS -> {
                //保存闹钟功能数据
//                lastConnect.bleDeviceList.forEach {
//                    SpUtil.putData(context!!, SECTION_ALARM, it.bleAddress, cmdCode)
//                }
                showToast("闹钟设置成功")
            }
            RX_ALARM_CANCEL_SUCCESS -> {
                showToast("闹钟取消成功")
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onFunctionEvent(event: FunChangeEvent) {
        when (event.fragCode) {
            EArea.ALARM.key -> {
                lastConnect.surface?.alarmList?.let {
                    showFrag()
//                    if (it.size > 0 && !lastConnect.isAlarmInit) {
//                        lastConnect.isAlarmInit = true
//                        showFrag()
//                    }
                }
            }
        }
    }

    //闹钟数据回传
    private fun showFrag() {
//        if (alarmList.size > 0) {
        lastConnect.surface?.alarmList?.let {
            if (it.size > 0) {
                alarmMemFragAdapter.setData(it)
                alarmMsgFragAdapter.setData(it)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    timePicker.hour = Calendar.getInstance()[Calendar.HOUR_OF_DAY]
                    mHour = timePicker.hour
                    timePicker.minute = Calendar.getInstance()[Calendar.MINUTE]
                    mMinute = timePicker.minute
                }
            }
        }

    }


    override fun initDestroy() {
        EventBus.getDefault().unregister(this)
    }

    private fun setTimePicker() {
        goldenColor = ContextCompat.getColor(AppContext.instance(), R.color.color_golden_dark_n)
        whiteColor = ContextCompat.getColor(AppContext.instance(), R.color.color_white)

        val amPmId = Resources.getSystem().getIdentifier("amPm", "id", "android");//上下午
        val hourId: Int = Resources.getSystem().getIdentifier("hour", "id", "android") //小时数字选择器
        val dividerId: Int =
            Resources.getSystem().getIdentifier("divider", "id", "android") //时分分隔的那个冒号
        val minuteId: Int = Resources.getSystem().getIdentifier("minute", "id", "android") //分钟数字选择器

        val ampm: NumberPicker = timePicker.findViewById(amPmId);
        setNumberPickerDivider(ampm)

        val hourPicker: NumberPicker = timePicker.findViewById(hourId)
        setNumberPickerDivider(hourPicker)

        val textView: TextView = timePicker.findViewById(dividerId)
        textView.setText(":") //这个是时与分之间的分隔“：”
        textView.setTextColor(goldenColor)
        val minutePicker: NumberPicker = timePicker.findViewById(minuteId)
        setNumberPickerDivider(minutePicker)
    }


    fun setNumberPickerDivider(numberPicker: NumberPicker) {
        for (i in 0 until numberPicker.childCount) {
            try {
                //选中项的Text颜色和粗体
                val etSelect: EditText = numberPicker.getChildAt(i) as EditText
                etSelect.setTextColor(goldenColor)
//                etSelect.getPaint().setTypeface(Typeface.DEFAULT_BOLD) //粗体
                //上下轮转的Text属性
                val wheelpaint_field: Field = numberPicker.javaClass.getDeclaredField(
                    "mSelectorWheelPaint"
                )
                wheelpaint_field.setAccessible(true)
                val paint: Paint = wheelpaint_field.get(numberPicker) as Paint
                paint.setColor(goldenColor) //洋红色
                //                paint.setTypeface(Typeface.DEFAULT_BOLD);//粗体
                //分割线颜色
                val dividerField: Field =
                    numberPicker.javaClass.getDeclaredField("mSelectionDivider")
                dividerField.setAccessible(true)
                dividerField.set(numberPicker, ColorDrawable(goldenColor))
                //分割线高度
                val heightField: Field = numberPicker.javaClass.getDeclaredField(
                    "mSelectionDividerHeight"
                )
                heightField.setAccessible(true)
                heightField.set(numberPicker, 2) //px
                numberPicker.invalidate()
            } catch (e: NoSuchFieldException) {
                e.printStackTrace()
            } catch (e: IllegalAccessException) {
                e.printStackTrace()
            } catch (e: IllegalArgumentException) {
                e.printStackTrace()
            }
        }
    }
}